package com.heima.wemedia.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.apis.article.IArticleClient;
import com.heima.apis.schedule.IScheduleClient;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.schedule.dto.Task;
import com.heima.model.wemedia.dtos.NewsAuthDto;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;

import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.model.wemedia.vo.WmNewsVo;
import com.heima.utils.ProtostuffUtil;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.AutoScanService;
import com.heima.wemedia.service.WmNewsService;
import com.heima.wemedia.threadLocal.WmUserThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Service
@Slf4j
@Transactional
public class WmNewsServiceImpl  extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

    @Autowired
    private WmNewsMapper wmNewsMapper;
    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;
    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    @Autowired
  private AutoScanService autoScanService ;
    @Autowired
    private IArticleClient iArticleClient;


    @Autowired
    private WmUserMapper wmUserMapper;
    @Override
    public ResponseResult newsList(WmNewsPageReqDto dto) {
        if (dto == null){
            return new PageResponseResult(0,0,0);
        }
        LambdaQueryWrapper<WmNews> wrapper = new LambdaQueryWrapper<>();
        //状态查询
        Short status = dto.getStatus();
        wrapper.eq(status!=null,WmNews::getStatus, status);
        //发布时间范围查询
        Date beginPubDate = dto.getBeginPubDate();
        Date endPubDate = dto.getEndPubDate();
        wrapper.between(beginPubDate !=null &&endPubDate != null,WmNews::getPublishTime,beginPubDate,endPubDate);

        //频道查询
        Integer channelId = dto.getChannelId();
        wrapper.eq(channelId!= null,WmNews::getChannelId,channelId);
        //关键字查询
        String keyword = dto.getKeyword();
        wrapper.like(StringUtils.isNotEmpty(keyword),WmNews::getTitle,keyword);
        //查询当前用户的文章
        wrapper.eq(WmNews::getUserId, WmUserThreadLocal.get().getId());
        //根据发布时间进行降序排序
        wrapper.orderByDesc(WmNews::getPublishTime);
        //构建分页查询
        Integer dtoPage = dto.getPage();
        Integer size = dto.getSize();
        Page<WmNews>page = new Page<>(dtoPage,size);
        //执行分页查询

        Page<WmNews> wmNewsPageResult =wmNewsMapper.selectPage(page,wrapper);
        Long total =wmNewsPageResult.getTotal();
        //构建返回值并返回
        PageResponseResult pageResult= new PageResponseResult(dtoPage,size,total.intValue());

        pageResult.setData(wmNewsPageResult.getRecords());


        return pageResult;
    }

    @Autowired
    private IScheduleClient scheduleClient;
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public ResponseResult submit(WmNewsDto dto) {

        //1.提取新闻内容
        WmNews wmNewsnews = getNews(dto);
        if (wmNewsnews == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }

        //2.//插入新闻表
        int newsResult = wmNewsMapper.insert(wmNewsnews);
        if (newsResult < 1) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }
        //3.判断是否为草稿
        Short status = dto.getStatus();
        //如果状态是0，判定为草稿，返回成功
        if (status == 0) {
            return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
        }

        //4.提取内容图
        String content = dto.getContent();
        List<String> contentImages = getContentImages(content);

        //5.提取封面图
        List<String> images = dto.getImages();
        Short type = dto.getType();
        List<String> coverImages = getCoverImages(type, images, contentImages);
        //6.插入内容图
        Boolean contentImageResult = addMaterial(wmNewsnews.getId(), contentImages, 0);
        if (!contentImageResult) {
            throw new RuntimeException("内容图添加失败");
        }
        //7.插入封面图
        Boolean coverImageResult = addMaterial(wmNewsnews.getId(), coverImages, 1);
        if (!coverImageResult) {
            throw new RuntimeException("封面图添加失败");
        }

        //8.调用审核代码
        try {
            autoScanService.autoScanWmNews(wmNewsnews.getId().longValue());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //调用client
//        Boolean addToTaskResult = addToTask(wmNewsnews.getId(), wmNewsnews.getPublishTime().getTime());
//
//        if (!addToTaskResult){
//            throw  new RuntimeException("添加任务失败");
//        }
//
      return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    //通过kafka发布和下架文章
    @Autowired
    private KafkaTemplate kafkaTemplate;

    @Override
    public ResponseResult downOrUp(WmNewsDto wmNewsDto) {
        //判断wmnews是否为空
        if (wmNewsDto ==  null){
            log.warn("缺少参数");
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE,"缺少参数");
        }
        //判断新闻是否为空
        Integer id = wmNewsDto.getId();
        WmNews wmNews = wmNewsMapper.selectById(id);
        if (wmNews == null ){
            log.warn("新闻为空");
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE,"新闻为空");
        }
        //判断新闻状态
        Short status = wmNews.getStatus();
        if (status != 9){
            log.warn("新闻不是发布状态");
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"新闻不是发布状态");
        }
        //修改新闻
        wmNews.setEnable(wmNewsDto.getEnable());
        //更新id
        int updateById = wmNewsMapper.updateById(wmNews);
        if (updateById <1 ){
            log.warn("新闻更新失败");
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"新闻更新失败");
        }

        Map <String ,Object> map = new HashMap<>();
       map.put("articledId",wmNews.getArticleId());
          map.put("enable",wmNews.getEnable());
        kafkaTemplate.send("topic",JSON.toJSONString(map));


        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
    //文章列表查询
    @Override
    public ResponseResult findList(NewsAuthDto dto) {
        dto.checkParam();

        // 2.记录当前页
        int currentPage = dto.getPage();

        // 3.分页查询+count查询
        dto.setPage((dto.getPage() - 1) * dto.getSize());
        List<WmNewsVo> wmNewsVoList = wmNewsMapper.findListAndPage(dto);
        int count = wmNewsMapper.findListCount(dto);

        // 4.结果返回
        ResponseResult responseResult = new PageResponseResult(currentPage, dto.getSize(), count);
        responseResult.setData(wmNewsVoList);
        return responseResult;
    }

    //查询文章详情
    @Override
    public ResponseResult findWmNewsVo(Integer id) {
        //判断入参
        if (id == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"id不能为空");

        }

        //查询文章信息
        WmNews wmNews = getById(id);
        if (wmNews == null){
            return  ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        //查询用户信息
        WmUser wmUser = wmUserMapper.selectById(wmNews.getId());
        //封装vo

        WmNewsVo wmNewsVo = new WmNewsVo();
        BeanUtils.copyProperties(wmNews,wmNewsVo);
        if (wmUser != null) {
            return ResponseResult.okResult(wmNewsVo);
        }
        return null;
    }


    //人工审核新闻拒绝
    @Override
    @Transactional (rollbackFor =  RuntimeException.class)
    public ResponseResult passOrFail(NewsAuthDto dto, Integer type) {
        if (dto == null ){
            return  ResponseResult.errorResult( AppHttpCodeEnum.PARAM_REQUIRE);

        }
        //获得id和msg
        Integer id = dto.getId();
        String msg = dto.getMsg();

        WmNews wmNews = wmNewsMapper.selectById(id);
        if (wmNews == null ){
            return  ResponseResult.errorResult( AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        int status = type == 1 ? 9 :2 ;
        wmNews.setStatus((short) status);
        wmNews.setReason( type == 1 ? "通过" : msg);
        int updateById = wmNewsMapper.updateById(wmNews);
        if (updateById < 1 ){
            return  ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"审核失败");
        }

//        if (type == 1) {
//               ArticleDto articleDto = autoScanService.wmNews2ArticleDto(wmNews);
//                ResponseResult responseResult = iArticleClient.saveArticle(articleDto);
//              if (responseResult == null || responseResult.getCode() != 200) {
//                  throw new RuntimeException("文章保存失败");
//               }
//          }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }


    private Boolean addToTask(Integer newsId ,Long executeTime){
        Task task = new Task();
        task.setExecuteTime(executeTime);
        task.getParameters();
        WmNews wmNews = new WmNews();
        wmNews.setId(newsId);
        task.setParameters(ProtostuffUtil.serialize(wmNews));
        ResponseResult responseResult = scheduleClient.addTask(task);
        if (responseResult !=null && responseResult.getCode() == 200){
            return true;
        }
        return false;

    }


    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean addMaterial(Integer newsId , List <String> imageList,Integer type){
        //判断imageList是否为空
        if (CollectionUtils.isEmpty(imageList)){
            return  true;
        }
        for (String url : imageList) {
            if (StringUtils.isEmpty(url)){
                continue;
            }
            WmMaterial material = new WmMaterial();
            material.setUserId(WmUserThreadLocal.get().getId());
            material.setUrl(url);
            material.setType((short) 0);
            material.setIsCollection((short) 0);
            material.setCreatedTime(new Date());
            int insertResult = wmMaterialMapper.insert(material);
            if (insertResult < 1){
                throw  new RuntimeException("素材添加失败");
            }
            WmNewsMaterial wmNewsMaterial = new WmNewsMaterial();
            wmNewsMaterial.setType(type.shortValue());
            wmNewsMaterial.setOrd((short) 1);
            wmNewsMaterial.setNewsId(material.getId());
            int insertResult2 = wmNewsMaterialMapper.insert(wmNewsMaterial);
            if (insertResult2 < 1){
                throw new RuntimeException("素材关系添加失败");
            }
        }
        return true;
    }
    //1.提取新闻内容
   public WmNews getNews(WmNewsDto dto){
        if (dto == null){
            log.warn("dto不可以为空");
            return null;
        }
        WmNews wmNews = new WmNews();
        //copy
        BeanUtils.copyProperties(dto,wmNews);
        //-1是空，判断是不是-1
        if (dto.getType() == -1){
           wmNews.setType(null);
        }
        List<String> images = dto.getImages();
        String imagesString = StringUtils.join(images, ",");
        wmNews.setImages(imagesString);
        wmNews.setCreatedTime(new Date());
        wmNews.setUserId(WmUserThreadLocal.get().getApUserId());
        return wmNews;
    }
//    //2.提取内容图
    public List<String> getContentImages(String content){
        if (StringUtils.isEmpty(content)){
            return  new ArrayList<>();
        }
        List<String> urlList = new ArrayList<>();
        //将content转为集合
        List<Map> maps = JSON.parseArray(content,Map.class);
        //判断是否为空
        if (CollectionUtils.isEmpty(maps)){
            return new ArrayList<>();
        }
        //遍历集合
        for (Map map : maps) {
            if (CollectionUtils.isEmpty(map)){
                continue;
            }
            Object type = map.get("type");
            if ("image".equals(type)){
                String value = (String) map.get("value");
                urlList.add(value);
            }
        }
        return urlList;
    }
    //自动布局
    public List <String> getCoverImages (Short type ,List<String> images,List <String> contentImages){
        if (type == -1){
            int size = contentImages.size();
            if (size > 3 ){
                return contentImages.subList(0,2);
            }else if (size == 2){
                return contentImages.subList(0,1);
            }else if (size == 1 ){
                List<String> list = new ArrayList<>();
                list.add(contentImages.get(0));
                return list;

            }else {
                return new ArrayList<>();
            }
        }
        return images;
    }
    public WmNews wmNresDto2WmNews(WmNewsDto wmNewsDto){
        if (wmNewsDto == null){
            return  null;
        }
        WmNews wmNews = new WmNews();
        //自动映射，copy
        BeanUtils.copyProperties(wmNewsDto,wmNews);
        //额外的字段
        wmNews.setUserId(WmUserThreadLocal.get().getId());
        wmNews.setCreatedTime(new Date());
        wmNews.setEnable((short) 1);
        //如果获得的字段是-1，返回空
        if (wmNewsDto.getType() == -1 ){
            wmNews.setType(null);
        }
        List <String> images =wmNewsDto.getImages();
        if (!CollectionUtils.isEmpty(images)){
            String join = StringUtils.join(images, ",");
            wmNews.setImages(join);

        }
        return wmNews;
    }


}
